package com.huatai.datacenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huatai.common.util.CollectionUtil;
import com.huatai.datacenter.entity.DataSourceEntity;
import com.huatai.datacenter.entity.SyncTableEntity;
import com.huatai.datacenter.entity.TopicTaskEntity;
import com.huatai.datacenter.entity.postdata.HttpRequestEntity;
import com.huatai.datacenter.entity.subject.SubjectBarGraphVO;
import com.huatai.datacenter.entity.subject.SubjectDirectoryEntity;
import com.huatai.datacenter.entity.subject.SubjectNodeVO;
import com.huatai.datacenter.entity.subject.SubjectTaskVO;
import com.huatai.datacenter.mapper.SubjectDataSetMapper;
import com.huatai.datacenter.service.*;
import com.huatai.dataservice.dubbo.SubjectDataSetDubboApi;
import com.huatai.dataservice.entity.SubjectDataSetEntity;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author gusiyi
 * @version 1.0
 * @className SubjectDataSetServiceImpl
 * @description 描述：
 * @date 2023/6/7 11:58
 */
@Service
public class SubjectDataSetServiceImpl extends ServiceImpl<SubjectDataSetMapper, SubjectDataSetEntity> implements SubjectDataSetService {

	static final String REDIS_KEY_YAXIS = "subjectDataSetYAxis_list";

	static final String REDIS_KEY_XAXIS = "subjectDataSetXAxis_list";

	@Autowired
	private SubjectDirectoryService subjectDirectoryService;

	@Autowired
	private TopicTaskService topicTaskService;

	@Autowired
	private HttpRequestService httpRequestService;

	@Autowired
	private DataSourceService dataSourceService;

	@Autowired
	private SyncTaskService syncTaskService;

	@Autowired
	private StringRedisTemplate redisTemplate;

	@DubboReference
	private SubjectDataSetDubboApi subjectDataSetDubboApi;

	@Override
	public SubjectNodeVO getSubjectTree(Integer typeContent1) {
		LambdaQueryWrapper<SubjectDirectoryEntity> directoryQuery = Wrappers.lambdaQuery();
		directoryQuery
			.eq(SubjectDirectoryEntity::getDeleted,false).eq(SubjectDirectoryEntity::getTypeContent,typeContent1);
		List<SubjectDirectoryEntity> directoryList = subjectDirectoryService.list(directoryQuery);
		List<Long> directoryIds = new ArrayList<>(directoryList.size());
		for (SubjectDirectoryEntity subjectDirectoryEntity : directoryList) {
			directoryIds.add(subjectDirectoryEntity.getId());
		}
		LambdaQueryWrapper<SubjectDataSetEntity> dataSetQuery = Wrappers.lambdaQuery();
		dataSetQuery
			.eq(SubjectDataSetEntity::getDeleted,false)
			.in(SubjectDataSetEntity::getSubjectDirectoryId,directoryIds);
		List<SubjectDataSetEntity> dataSetList = list(dataSetQuery);
		List<SubjectNodeVO> directoryNodeList = new ArrayList<>(directoryList.size());
		for (SubjectDirectoryEntity subjectDirectoryEntity : directoryList) {
			SubjectNodeVO subjectNodeVO = new SubjectNodeVO();
			subjectNodeVO.setId(subjectDirectoryEntity.getId());
			subjectNodeVO.setParentId(1L);
			subjectNodeVO.setNodeType("主题目录");
			subjectNodeVO.setNodeName(subjectDirectoryEntity.getSubjectDirectoryName());
			List<SubjectNodeVO> dataSetNodeList = new ArrayList<>(dataSetList.size());
			for (SubjectDataSetEntity subjectDataSetEntity : dataSetList) {
				if (subjectDirectoryEntity.getId().equals(subjectDataSetEntity.getSubjectDirectoryId())){
					SubjectNodeVO dataSetNode = new SubjectNodeVO();
					dataSetNode.setId(subjectDataSetEntity.getId());
					dataSetNode.setParentName(subjectDirectoryEntity.getSubjectDirectoryName());
					dataSetNode.setParentId(subjectDataSetEntity.getSubjectDirectoryId());
					dataSetNode.setNodeName(subjectDataSetEntity.getSubjectDataSetName());
					dataSetNode.setNodeType("数据集");
					dataSetNode.setChildren(null);
					dataSetNodeList.add(dataSetNode);
				}
			}
			subjectNodeVO.setChildren(dataSetNodeList);
			directoryNodeList.add(subjectNodeVO);
		}
		SubjectNodeVO subjectDataCenter = new SubjectNodeVO();
		subjectDataCenter.setId(1L);
		subjectDataCenter.setParentId(0L);
		subjectDataCenter.setNodeName("主题数据中心");
		subjectDataCenter.setNodeType("顶级目录");
		subjectDataCenter.setChildren(directoryNodeList);
		return subjectDataCenter;
	}

	@Override
	public Page<LinkedHashMap<String,Object>> getDataSetInfo(SubjectDataSetEntity subjectDataSetEntity) {
		SubjectDataSetEntity dataSet = getById(subjectDataSetEntity.getId());
		dataSet.setPageIndex(subjectDataSetEntity.getPageIndex());
		dataSet.setPageSize(subjectDataSetEntity.getPageSize());
		return subjectDataSetDubboApi.getDataSetInfo(dataSet);
	}

	@Override
	public List<SubjectTaskVO> getDataAccessTask(SubjectDataSetEntity dataSetEntity) {
		Integer dataAccessTaskTypeNum = dataSetEntity.getDataAccessTaskTypeNum();
		switch (dataAccessTaskTypeNum){
			case 1:{
				//实时数据接入 kafka
				LambdaQueryWrapper<TopicTaskEntity> taskQuery = Wrappers.lambdaQuery();
				taskQuery.select(TopicTaskEntity::getTopicName,TopicTaskEntity::getDataTable);
				List<TopicTaskEntity> topicTaskEntities = topicTaskService.list(taskQuery);
				List<SubjectTaskVO> resultList = new ArrayList<>(topicTaskEntities.size());
				for (TopicTaskEntity topicTaskEntity : topicTaskEntities) {
					SubjectTaskVO resultTask = new SubjectTaskVO();
					resultTask.setDataAccessTaskName(topicTaskEntity.getTopicName());
					resultTask.setDataAccessTaskTable(topicTaskEntity.getDataTable());
					resultList.add(resultTask);
				}
				return resultList;
			}
			case 2: {
				//HTTP数据接入
				LambdaQueryWrapper<HttpRequestEntity> httpQuery = Wrappers.lambdaQuery();
				httpQuery.select(HttpRequestEntity::getJoinName, HttpRequestEntity::getTableName);
				List<HttpRequestEntity> httpRequestEntities = httpRequestService.list(httpQuery);
				List<SubjectTaskVO> resultList = new ArrayList<>(httpRequestEntities.size());
				for (HttpRequestEntity httpRequestEntity : httpRequestEntities) {
					SubjectTaskVO resultTask = new SubjectTaskVO();
					resultTask.setDataAccessTaskName(httpRequestEntity.getJoinName());
					resultTask.setDataAccessTaskTable(httpRequestEntity.getTableName());
					resultList.add(resultTask);
				}
				return resultList;
			}
			case 3:{
				//库表同步
				LambdaQueryWrapper<DataSourceEntity> dataSourceQuery = Wrappers.lambdaQuery();
				String subjectDataBaseName = "ht_dataservice";
				String subjectConnectName = "主题库";
				dataSourceQuery
					.eq(DataSourceEntity::getConnectName,subjectConnectName)
					.eq(DataSourceEntity::getDatabaseName, subjectDataBaseName);
				//获取主题库实体类
				DataSourceEntity dataSourceEntity = dataSourceService.getOne(dataSourceQuery);
				LambdaQueryWrapper<SyncTableEntity> syncTableQuery = Wrappers.lambdaQuery();
				syncTableQuery
					.eq(SyncTableEntity::getTargetSourceId,dataSourceEntity.getId());
				//获取目标库为主题库的库表同步记录
				List<SyncTableEntity> syncTableEntities = syncTaskService.list(syncTableQuery);
				List<SubjectTaskVO> resultList = new ArrayList<>(syncTableEntities.size());
				for (SyncTableEntity syncTableEntity : syncTableEntities) {
					SubjectTaskVO resultTask = new SubjectTaskVO();
					resultTask.setDataAccessTaskName(syncTableEntity.getSyncTaskName());
					resultTask.setDataAccessTaskTable(syncTableEntity.getSyncTableName());
					resultList.add(resultTask);
				}
				return resultList;
			}
			default:
				return new ArrayList<>();
		}
	}

	@Override
	public void addDataSetCountBarGraph() {
		LambdaQueryWrapper<SubjectDataSetEntity> dataSetQuery = Wrappers.lambdaQuery();
		dataSetQuery.eq(SubjectDataSetEntity::getDeleted,false);
		List<SubjectDataSetEntity> dataSetList = list(dataSetQuery);
		redisTemplate.delete(REDIS_KEY_YAXIS);
		redisTemplate.delete(REDIS_KEY_XAXIS);
		for (SubjectDataSetEntity subjectDataSetEntity : dataSetList) {
			String tableName = subjectDataSetEntity.getDataAccessTaskTable();
			Long tableCount = subjectDataSetDubboApi.getDataSetCountByTableName(tableName);
			redisTemplate.opsForList().leftPush(REDIS_KEY_YAXIS, String.valueOf(tableCount));
			redisTemplate.opsForList().leftPush(REDIS_KEY_XAXIS, subjectDataSetEntity.getSubjectDataSetName());
		}
	}

	@Override
	public SubjectBarGraphVO getDataSetBarGraphVO(Integer index) {
		Map<String, List<String>> dataSetMap = getDataSetInfoByRedis();
		List<String> xAxisData = dataSetMap.get("xData");
		List<String> yAxisData = dataSetMap.get("yData");
		List<String> xAxisDataList = new ArrayList<>();
		List<String> yAxisDataList = new ArrayList<>();
		if (yAxisData.size()<7){
			//当数据集的种类不超过7种时，展示所有
			for (int i = 0; i < yAxisData.size(); i++) {
				xAxisDataList.add(xAxisData.get(i));
				yAxisDataList.add(yAxisData.get(i));
			}
		}else {
			//当数据集的种类超过7种时，根据index进行循环展示
			int times = 0;
			for (;; index++) {
				if (index >= yAxisData.size()){
					index=0;
				}
				if (times >= 7){
					break;
				}
				xAxisDataList.add(xAxisData.get(index));
				yAxisDataList.add(yAxisData.get(index));
				times++;
			}
		}
		SubjectBarGraphVO result = new SubjectBarGraphVO();
		result.setXAxis(xAxisDataList);
		result.setYAxis(yAxisDataList);
		result.setIndex(index);
		return result;
	}

	private Map<String,List<String>> getDataSetInfoByRedis(){
		List<String> yAxixData = redisTemplate.opsForList().range(REDIS_KEY_YAXIS, 0, -1);
		List<String> xAxisData = redisTemplate.opsForList().range(REDIS_KEY_XAXIS, 0, -1);
		if (CollectionUtil.isEmpty(yAxixData) || CollectionUtil.isEmpty(xAxisData)){
			addDataSetCountBarGraph();
		}
		yAxixData = redisTemplate.opsForList().range(REDIS_KEY_YAXIS, 0, -1);
		xAxisData = redisTemplate.opsForList().range(REDIS_KEY_XAXIS, 0, -1);
		if (CollectionUtil.isEmpty(yAxixData) || CollectionUtil.isEmpty(xAxisData)){
			yAxixData = new ArrayList<>(0);
			xAxisData = new ArrayList<>(0);
		}
		Map<String,List<String>> resultMap = new HashMap<>(2);
		resultMap.put("xData",xAxisData);
		resultMap.put("yData",yAxixData);
		return resultMap;
	}




}
